package com.sairobo.live.auth;

import com.sairobo.live.util.AccessStateHelper;
import com.sairobo.live.util.TokenUtils;
import com.sairobo.live.util.SpringUtil;
import com.sairobo.live.web.vo.response.ResponseStatus;
import com.netflix.zuul.context.RequestContext;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 鉴权管理器,分配具体鉴权操作
 */
public class AuthManager {

    private RequestContext ctx;

    public AuthManager(RequestContext ctx) {
        this.ctx = ctx;
    }

    Map<String, TokenAuth> authMap = new HashMap<>();

    /**
     * 根据token前缀获取对应的鉴权执行者
     *
     * @return TokenAuth
     */
    private TokenAuth getAuthByPrefix(String token) {
        String prefix = token.split(":")[0];
        return authMap.get(prefix);
    }

    /**
     * 添加具体鉴权类
     *
     * @param tokenAuth
     */
    public AuthManager addAuthImpl(TokenAuth tokenAuth) {
        authMap.put(tokenAuth.getPrefix(), tokenAuth);
        return this;
    }

    /**
     * 执行校验
     */
    public void doAuth() throws IOException {
        TokenUtils tokenUtils = SpringUtil.getBean(TokenUtils.class);

        // 如果需要鉴权,根据token的前缀判断执行哪个鉴权子类
        String token = ctx.getRequest().getHeader("Authorization");

        if (!tokenUtils.isExistedAuthorization(ctx.getRequest())) {
            //token检验
            AccessStateHelper.responseHandler(ctx, ResponseStatus.NO_AUTHORIZATION);
        } else {
            //token存在，那么对应找到各自的鉴权类
            TokenAuth tokenAuth = getAuthByPrefix(token);
            if (null != tokenAuth) {
                tokenAuth.run(ctx,getAuthorization(token));
            } else {
                //如果提供token未含前缀或未找到匹配的验证器,说明为伪造则提示参数不合法
                AccessStateHelper.responseHandler(ctx, ResponseStatus.INVALID_TOKEN_PARAM);
            }
        }
    }


    /**
     * 排除掉 prefix 标识属于哪个app
     * authorization由两部分组成 <prefix>:<access_token>
     * @param authorization
     * @return
     */
    public static String getAuthorization(String authorization){
        authorization = authorization.split(":")[1];
        return authorization;
    }
}
